﻿$.extend($.Engine.Math, {
  //是否是合法浮点数
  IsValid: function (x) {
    return isFinite(x);
  },
  //向量点积
  Dot: function (a, b) {
    return a.x * b.x + a.y * b.y;
  },
  //向量差积
  CrossVV: function (a, b) {
    return a.x * b.y - a.y * b.x;
  },
  CrossVF: function (a, s) {
    var v = new $.Engine.Math.Vector2D(s * a.y, -s * a.x);
    return v;
  },
  CrossFV: function (s, a) {
    var v = new $.Engine.Math.Vector2D(-s * a.y, s * a.x);
    return v;
  },
  MulMV: function (A, v) {
    var u = new $.Engine.Math.Vector2D(A.col1.x * v.x + A.col2.x * v.y, A.col1.y * v.x + A.col2.y * v.y);
    return u;
  },
  MulTMV: function (A, v) {
    var u = new $.Engine.Math.Vector2D(this.Dot(v, A.col1), this.Dot(v, A.col2));
    return u;
  },
  AddVV: function (a, b) {
    var v = new $.Engine.Math.Vector2D(a.x + b.x, a.y + b.y);
    return v;
  },
  SubtractVV: function (a, b) {
    var v = new $.Engine.Math.Vector2D(a.x - b.x, a.y - b.y);
    return v;
  },
  MulFV: function (s, a) {
    var v = new $.Engine.Math.Vector2D(s * a.x, s * a.y);
    return v;
  },
  AddMM: function (A, B) {
    var C = new $.Engine.Math.Mat2D(0, this.AddVV(A.col1, B.col1), this.AddVV(A.col2, B.col2));
    return C;
  },
  MulMM: function (A, B) {
    var C = new $.Engine.Math.Mat2D(0, this.MulMV(A, B.col1), this.MulMV(A, B.col2));
    return C;
  },
  MulTMM: function (A, B) {
    var c1 = new $.Engine.Math.Vector2D(this.Dot(A.col1, B.col1), this.Dot(A.col2, B.col1));
    var c2 = new $.Engine.Math.Vector2D(this.Dot(A.col1, B.col2), this.Dot(A.col2, B.col2));
    var C = new $.Engine.Math.Mat2D(0, c1, c2);
    return C;
  },
  Abs: function (a) {
    return a > 0.0 ? a : -a;
  },
  AbsV: function (a) {
    var b = new $.Engine.Math.Vector2D(this.Abs(a.x), this.Abs(a.y));
    return b;
  },
  AbsM: function (A) {
    var B = new $.Engine.Math.Mat2D(0, this.AbsV(A.col1), this.AbsV(A.col2));
    return B;
  },
  Min: function (a, b) {
    return a < b ? a : b;
  },
  MinV: function (a, b) {
    var c = new $.Engine.Math.Vector2D(this.Min(a.x, b.x), this.Min(a.y, b.y));
    return c;
  },
  Max: function (a, b) {
    return a > b ? a : b;
  },
  MaxV: function (a, b) {
    var c = new $.Engine.Math.Vector2D(this.Max(a.x, b.x), this.Max(a.y, b.y));
    return c;
  },
  Clamp: function (a, low, high) {
    return this.Max(low, this.Min(a, high));
  },
  ClampV: function (a, low, high) {
    return this.MaxV(low, this.MinV(a, high));
  },
  Swap: function (a, b) {
    var tmp = a[0];
    a[0] = b[0];
    b[0] = tmp;
  },
  Random: function () {
    return Math.random() * 2 - 1;
  },
  NextPowerOfTwo: function (x) {
    x |= (x >> 1) & 0x7FFFFFFF;
    x |= (x >> 2) & 0x3FFFFFFF;
    x |= (x >> 4) & 0x0FFFFFFF;
    x |= (x >> 8) & 0x00FFFFFF;
    x |= (x >> 16) & 0x0000FFFF;
    return x + 1;
  },
  IsPowerOfTwo: function (x) {
    var result = x > 0 && (x & (x - 1)) == 0;
    return result;
  }
});